/*
 * Copyright 2018- The Pixie Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

syntax = "proto3";

package px.services;

option go_package = "profilepb";

import "github.com/gogo/protobuf/gogoproto/gogo.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/wrappers.proto";
import "src/api/proto/uuidpb/uuid.proto";

// Profile service tracks the user and organization profile information.
service ProfileService {
  rpc CreateUser(CreateUserRequest) returns (px.uuidpb.UUID);
  rpc GetUser(px.uuidpb.UUID) returns (UserInfo);
  rpc GetUserByEmail(GetUserByEmailRequest) returns (UserInfo);
  rpc GetUserByAuthProviderID(GetUserByAuthProviderIDRequest) returns (UserInfo);
  // Creates the initial organization with the specified user as the owner.
  rpc CreateOrgAndUser(CreateOrgAndUserRequest) returns (CreateOrgAndUserResponse);
  rpc UpdateUser(UpdateUserRequest) returns (UserInfo);
  // Calls for handling user settings.
  rpc GetUserSettings(GetUserSettingsRequest) returns (GetUserSettingsResponse);
  rpc UpdateUserSettings(UpdateUserSettingsRequest) returns (UpdateUserSettingsResponse);
  // Calls for handling user attributes.
  rpc GetUserAttributes(GetUserAttributesRequest) returns (GetUserAttributesResponse);
  rpc SetUserAttributes(SetUserAttributesRequest) returns (SetUserAttributesResponse);
  rpc DeleteUser(DeleteUserRequest) returns (DeleteUserResponse);
}

// Org service tracks organization information.
service OrgService {
  rpc GetOrg(px.uuidpb.UUID) returns (OrgInfo);
  rpc GetOrgByName(GetOrgByNameRequest) returns (OrgInfo);
  rpc GetOrgByDomain(GetOrgByDomainRequest) returns (OrgInfo);
  rpc UpdateOrg(UpdateOrgRequest) returns (OrgInfo);
  rpc CreateOrg(CreateOrgRequest) returns (px.uuidpb.UUID);
  rpc GetOrgs(GetOrgsRequest) returns (GetOrgsResponse);
  rpc GetUsersInOrg(GetUsersInOrgRequest) returns (GetUsersInOrgResponse);
  rpc AddOrgIDEConfig(AddOrgIDEConfigRequest) returns (AddOrgIDEConfigResponse);
  rpc DeleteOrgIDEConfig(DeleteOrgIDEConfigRequest) returns (DeleteOrgIDEConfigResponse);
  rpc GetOrgIDEConfigs(GetOrgIDEConfigsRequest) returns (GetOrgIDEConfigsResponse);

  rpc CreateInviteToken(CreateInviteTokenRequest) returns (InviteToken);
  rpc RevokeAllInviteTokens(px.uuidpb.UUID) returns (google.protobuf.Empty);
  rpc VerifyInviteToken(InviteToken) returns (VerifyInviteTokenResponse);
}

// UserInfo has information about a single end user in our system.
message UserInfo {
  // The ID of the user.
  px.uuidpb.UUID id = 1 [ (gogoproto.customname) = "ID" ];
  // The ID of the organization that they belong to.
  px.uuidpb.UUID org_id = 2 [ (gogoproto.customname) = "OrgID" ];
  string first_name = 4;
  string last_name = 5;
  string email = 6;
  string profile_picture = 7;
  bool is_approved = 8;
  string identity_provider = 9;
  // The auth_provider_id is the user ID that an auth_provider uses for an ID of the corresponding
  // user.
  string auth_provider_id = 10 [ (gogoproto.customname) = "AuthProviderID" ];

  reserved 3;
}

message GetUserByEmailRequest {
  string email = 1;
}

message GetUserByAuthProviderIDRequest {
  // The auth_provider_id is the user ID that an auth_provider uses for an ID of the corresponding
  // user.
  string auth_provider_id = 1 [ (gogoproto.customname) = "AuthProviderID" ];
}

// OrgInfo contains information about a company in our system.
message OrgInfo {
  // The ID of the organization.
  px.uuidpb.UUID id = 1 [ (gogoproto.customname) = "ID" ];
  // The name of the organization (this is currently the same as the domain_name below and is the
  // last part of the email).
  string org_name = 2;
  // The domain that the user belongs to, if they have one. Some older users will not have this
  // field set and will be null.
  google.protobuf.StringValue domain_name = 3;
  // Whether this org requires admin approval to authorize new users.
  bool enable_approvals = 4;
}

message CreateUserRequest {
  // Optional, the org_id (if any) that this user should belong to.
  px.uuidpb.UUID org_id = 1 [ (gogoproto.customname) = "OrgID" ];
  string first_name = 3;
  string last_name = 4;
  string email = 5;
  string identity_provider = 6;
  // The auth_provider_id is the user ID that an auth_provider uses for an ID of the corresponding
  // user.
  string auth_provider_id = 7 [ (gogoproto.customname) = "AuthProviderID" ];

  reserved 2;
}

message CreateOrgAndUserRequest {
  message Org {
    string org_name = 1;
    string domain_name = 2;
  }
  message User {
    string first_name = 2;
    string last_name = 3;
    string email = 4;
    string identity_provider = 5;
    // The auth_provider_id is the user ID that an auth_provider uses for an ID of the corresponding
    // user.
    string auth_provider_id = 6 [ (gogoproto.customname) = "AuthProviderID" ];

    reserved 1;
  }
  Org org = 1;
  User user = 2;
}

message CreateOrgAndUserResponse {
  px.uuidpb.UUID org_id = 1 [ (gogoproto.customname) = "OrgID" ];
  px.uuidpb.UUID user_id = 2 [ (gogoproto.customname) = "UserID" ];
}

message CreateOrgRequest {
  string org_name = 1;
  google.protobuf.StringValue domain_name = 2;
}

message GetOrgByNameRequest {
  string name = 1;
}

message GetOrgByDomainRequest {
  string domain_name = 1;
}

message GetOrgsRequest {}

message GetOrgsResponse {
  repeated OrgInfo orgs = 1;
}

// DeleteUserRequest is a request to delete a user. This request must be made with the user's
// credentials.
message DeleteUserRequest {
  // The ID of the user.
  px.uuidpb.UUID id = 1 [ (gogoproto.customname) = "ID" ];
}

// DeleteUserResponse is the response to a user deletion request.
message DeleteUserResponse {}

message UpdateUserRequest {
  // The ID of the user.
  px.uuidpb.UUID id = 1 [ (gogoproto.customname) = "ID" ];
  google.protobuf.StringValue display_picture = 3;
  google.protobuf.BoolValue is_approved = 4;
  px.uuidpb.UUID org_id = 5 [ (gogoproto.customname) = "OrgID" ];
  ;
  // This used to be `profile_picture` which has been replaced with `display_picture`
  // which correctly uses google's StringValues.
  reserved 2;
}

message UpdateOrgRequest {
  // The ID of the org.
  px.uuidpb.UUID id = 1 [ (gogoproto.customname) = "ID" ];
  // Whether to enable/disable the requirement for admins to approve new users.
  google.protobuf.BoolValue enable_approvals = 2;
  google.protobuf.StringValue domain_name = 3;
}

// A request to get the user settings for a particular user.
message GetUserSettingsRequest {
  // The ID of the user.
  px.uuidpb.UUID id = 1 [ (gogoproto.customname) = "ID" ];
  reserved 2;  // DEPRECATED
}

// The response for a UserSettingsRequest.
message GetUserSettingsResponse {
  // Settings for users key-value.
  reserved 1;  // DEPRECATED
  reserved 2;  // DEPRECATED
  bool analytics_optout = 3;
}

// A request to update the user settings for a particular user.
message UpdateUserSettingsRequest {
  // The ID of the user.
  px.uuidpb.UUID id = 1 [ (gogoproto.customname) = "ID" ];
  reserved 2;  // DEPRECATED
  reserved 3;  // DEPRECATED
  google.protobuf.BoolValue analytics_optout = 4;
}

// UpdateUserSettingsResponse is the response to an UpdateUserSettingsRequest.
message UpdateUserSettingsResponse {
  // Whether the update was successful.
  bool ok = 1 [ (gogoproto.customname) = "OK" ];
}

// A request to get user attributes for the given user.
message GetUserAttributesRequest {
  // The ID of the user.
  px.uuidpb.UUID id = 1 [ (gogoproto.customname) = "ID" ];
}

// The response for a GetUserAttributes call.
message GetUserAttributesResponse {
  bool tour_seen = 1;
}

// A request to set user attributes for the given user.
message SetUserAttributesRequest {
  // The ID of the user.
  px.uuidpb.UUID id = 1 [ (gogoproto.customname) = "ID" ];
  google.protobuf.BoolValue tour_seen = 2;
}

// The response for a SetUserAttributes call.
message SetUserAttributesResponse {}

// A request to get all users in the given org. This org must match the user's org,
// verified in the augmented token.
message GetUsersInOrgRequest {
  // The org to get the users of.
  px.uuidpb.UUID org_id = 1 [ (gogoproto.customname) = "OrgID" ];
}

// The response to a GetUsersInOrgRequest.
message GetUsersInOrgResponse {
  // The users in the requested org.
  repeated UserInfo users = 1;
}

// IDEConfig is used to configure an IDE with Pixie.
message IDEConfig {
  // The name of the IDE. For example: "github", "sourcemap".
  string ide_name = 1 [ (gogoproto.customname) = "IDEName" ];
  // A mustache.js template path for opening up a page in the IDE, given the symbol, function path,
  // and function. For example: "subl://{{.Path}}/{{.Symbol}}".
  string path = 2;
}

// AddOrgIDEConfigRequest is a request to add an IDE config for the given org.
message AddOrgIDEConfigRequest {
  // The org which the IDE config should be added to.
  px.uuidpb.UUID org_id = 1 [ (gogoproto.customname) = "OrgID" ];
  // The config that should be added to the org.
  IDEConfig config = 2;
}

// AddOrgIDEConfigResponse is the response for adding an IDE config to an org.
message AddOrgIDEConfigResponse {
  // The config that was added to the org.
  IDEConfig config = 1;
}

// DeleteOrgIDEConfigRequest is a request to delete an IDE config from an org.
message DeleteOrgIDEConfigRequest {
  // The org which the IDE config should be removed from.
  px.uuidpb.UUID org_id = 1 [ (gogoproto.customname) = "OrgID" ];
  // The name of the IDE config to be deleted.
  string ide_name = 2 [ (gogoproto.customname) = "IDEName" ];
}

// DeleteOrgIDEConfigResponse is the response to deleting an IDE config from an org.
message DeleteOrgIDEConfigResponse {}

// GetOrgIDEConfigsRequest is a request to get all IDE configs for an org.
message GetOrgIDEConfigsRequest {
  // The org to get the IDE configs for.
  px.uuidpb.UUID org_id = 1 [ (gogoproto.customname) = "OrgID" ];
  // Optional, the name of the IDE to fetch configs for. If not specified, fetches all configs for
  // the org.
  string ide_name = 2 [ (gogoproto.customname) = "IDEName" ];
}

// GetOrgIDEConfigsResponse is the response to getting all IDE configs for an org.
message GetOrgIDEConfigsResponse {
  // The IDE configs belonging to the org.
  repeated IDEConfig configs = 1;
}

message CreateInviteTokenRequest {
  px.uuidpb.UUID org_id = 1 [ (gogoproto.customname) = "OrgID" ];
}

message InviteToken {
  string signed_claims = 1;
}

message VerifyInviteTokenResponse {
  // Tells you if the invite is valid or not.
  bool valid = 1;
  // If valid, the org that this invite belongs to.
  px.uuidpb.UUID org_id = 2 [ (gogoproto.customname) = "OrgID" ];
}
